/**********************************************************

@description:
*File Name:init.c
*Author: ydx
*mail: yudongxiang93@163.com
*Create Time: Tue 03 Jun 2025 09:49:07 AM CST
**********************************************************/
#include "init.h"
#include "types.h"
#include "boot_info.h"
#include "cpu.h"
#include "irq.h"
#include "cpu_instr.h"
#include "test.h"
#include "time.h"
#include "log.h"
#include "os_cfg.h"
#include "klib.h"
#include "task.h"
#include "list.h"
#include "sem.h"
#include "mem.h"
#include "console.h"
#include "kbd.h"
#include "mouse.h"
#include "fs.h"

static task_t   init_task;
static task_t   second_task;
static uint32_t init_task_stack[1024];
static uint32_t second_task_stack[1024];
static sem_t    sem;

void test1()
{
}
void kernel_init(boot_info_t *boot_info)
{
    ASSERT(boot_info->ram_region_count != 0);
    cpu_init();
    irq_init();
    log_init();
    // console_init(0);

    mem_init(boot_info);
    fs_init();

    time_init();
    task_manager_init();
    kbd_init();
    // mouse_init();
}
void init_task_entry(void)
{
    int count = 0;
    for (;;)
    {
        // sem_wait(&sem);
        log_printf("%s:%d", task_current_task()->name, count++);
        // sys_sleep(600);
        // task_switch_from_to(&init_task,task_first_task());
        // sys_sched_yield();
    }
}
void second_task_entry(void)
{
    int count = 0;
    for (;;)
    {
        // sem_wait(&sem);
        log_printf("%s:%d", task_current_task()->name, count++);
        // sys_sleep(600);
        // task_switch_from_to(&init_task,task_first_task());
        // sys_sched_yield();
    }
}
// in fact,it contains the privilege level, but in simple way, doesn't contains it
void mov_to_first_task(void)
{
    // method1:
    // void first_task_entry();
    // first_task_entry();
    task_t *current_task = task_current_task();
    ASSERT(current_task != 0);

    tss_t *tss = &(current_task->tss);
    /* __asm__ __volatile__(
         "jmp *%[ip]"::[ip]"r"(tss->eip)
     );*/
    __asm__ __volatile__("push %[ss]\n\t"
                         "push %[esp]\n\t"
                         "push %[eflags]\n\t"
                         "push %[cs]\t\n"
                         "push %[eip]\n\t"
                         "iret" ::[ss] "r"(tss->ss),
                         [esp] "r"(tss->esp),
                         [eflags] "r"(tss->eflags),
                         [cs] "r"(tss->cs),
                         [eip] "r"(tss->eip));
}

void init_main(void)
{
    log_printf("=====================================");
    log_printf("Kernel is running....");
    log_printf("version:%s", OS_VERSION);
    // int a=3/0;
    // task_init(&init_task,"init task",(uint32_t)init_task_entry,(uint32_t)&init_task_stack[1024]);
    // task_init(&second_task,"second task",(uint32_t)second_task_entry,(uint32_t)&second_task_stack[1024]);
    // task_init(task_first_task(),0,0);
    // ltr(first_task.tss_selector);
    task_first_init();    // the same as task_init(task_first_task(),0,0);&& ltr(first_task.tss_selector);
    mov_to_first_task();
    // sem_init(&sem,0);
    // irq_enable_global();
    // list_test();

    // int count=0;
    // for(;;){
    //     log_printf("%s: %d",task_current_task()->name,count++);
    // task_switch_from_to(task_first_task(),&init_task);
    // sys_sched_yield();
    // sem_notify(&sem);
    // sys_sleep(1000);
    //}
}